
import os
import sys
import re
import argparse

def gen_repeate_macro(out,format,count,start=1):
    for num in range(start, count):
        out.write(format.format(no=num,dec=num-1,inc=num+1))
        out.write('\n')

def KAGUYA_PP_REPEAT(out,count):
    out.write('#define KAGUYA_PP_REPEAT0(MACRO)\n')
    gen_repeate_macro(out,'#define KAGUYA_PP_REPEAT{no}(MACRO) KAGUYA_PP_REPEAT{dec}(MACRO) MACRO({no})',count)
    out.write('#define KAGUYA_PP_REPEAT(COUNT,MACRO) KAGUYA_PP_CAT(KAGUYA_PP_REPEAT,COUNT)(MACRO)\n')

def KAGUYA_PP_REPEAT_DEF(out,count):
    out.write('#define KAGUYA_PP_REPEAT_DEF0(MACRO)\n')
    gen_repeate_macro(out,'#define KAGUYA_PP_REPEAT_DEF{no}(MACRO) KAGUYA_PP_REPEAT_DEF{dec}(MACRO) MACRO({no})',count)
    out.write('#define KAGUYA_PP_REPEAT_DEF(COUNT,MACRO) KAGUYA_PP_CAT(KAGUYA_PP_REPEAT_DEF,COUNT)(MACRO)\n')

def KAGUYA_PP_REVERSE_REPEAT(out,count):
    out.write('#define KAGUYA_PP_REVERSE_REPEAT0(MACRO)\n')
    gen_repeate_macro(out,'#define KAGUYA_PP_REVERSE_REPEAT{no}(MACRO) MACRO({no}) KAGUYA_PP_REVERSE_REPEAT{dec}(MACRO)',count)
    out.write('#define KAGUYA_PP_REVERSE_REPEAT(COUNT,MACRO) KAGUYA_PP_CAT(KAGUYA_PP_REVERSE_REPEAT,COUNT)(MACRO)\n')

def KAGUYA_PP_REPEAT_ARG(out,count):
    out.write('#define KAGUYA_PP_REPEAT_ARG0(MACRO)\n')
    out.write('#define KAGUYA_PP_REPEAT_ARG1(MACRO) MACRO(1)\n')
    gen_repeate_macro(out,'#define KAGUYA_PP_REPEAT_ARG{no}(MACRO) KAGUYA_PP_REPEAT_ARG{dec}(MACRO), MACRO({no})',count,2)
    out.write('#define KAGUYA_PP_REPEAT_ARG(COUNT,MACRO) KAGUYA_PP_CAT(KAGUYA_PP_REPEAT_ARG,COUNT)(MACRO)\n')

def KAGUYA_PP_REPEAT_DEF_VA_ARG(out,count):
    out.write('#define KAGUYA_PP_REPEAT_DEF_VA_ARG0(MACRO, ...)\n')
    gen_repeate_macro(out,'#define KAGUYA_PP_REPEAT_DEF_VA_ARG{no}(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG{dec}(MACRO,__VA_ARGS__) MACRO({no},__VA_ARGS__))',count)
    out.write('#define KAGUYA_PP_REPEAT_DEF_VA_ARG(COUNT,MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_CAT(KAGUYA_PP_REPEAT_DEF_VA_ARG,COUNT)(MACRO,__VA_ARGS__))\n')

def KAGUYA_PP_WHILE(out,count):
    out.write('#define KAGUYA_PP_WHILE0(MACRO,R) R\n')
    gen_repeate_macro(out,'#define KAGUYA_PP_WHILE{no}(MACRO,R) MACRO(KAGUYA_PP_WHILE{dec}(MACRO,R))',count)
    out.write('#define KAGUYA_PP_WHILE(COUNT,R,MACRO) KAGUYA_PP_CAT(KAGUYA_PP_WHILE,COUNT)(MACRO,R)\n')


def KAGUYA_PP_INC(out,count):
    gen_repeate_macro(out,'#define KAGUYA_PP_INC{no} {inc}',count,0)
    out.write('#define KAGUYA_PP_INC(N) KAGUYA_PP_CAT(KAGUYA_PP_INC,N)\n')

def KAGUYA_PP_DEC(out,count):
    gen_repeate_macro(out,'#define KAGUYA_PP_DEC{no} {dec}',count)
    out.write('#define KAGUYA_PP_DEC(N) KAGUYA_PP_CAT(KAGUYA_PP_DEC,N)\n')

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("count", help="count of generate macro",type=int)
    args = parser.parse_args()
    out = sys.stdout
    out.write('//generated by '+__file__+'\n')
    out.write('#pragma once\n')
    KAGUYA_PP_REPEAT(out,args.count)
    out.write('\n\n')
    KAGUYA_PP_REPEAT_DEF(out,args.count)
    out.write('\n\n')
    KAGUYA_PP_REVERSE_REPEAT(out,args.count)
    out.write('\n\n')
    KAGUYA_PP_REPEAT_ARG(out,args.count)
    out.write('\n\n')
    KAGUYA_PP_REPEAT_DEF_VA_ARG(out,args.count)
    out.write('\n\n')
    KAGUYA_PP_WHILE(out,args.count)
    out.write('\n\n')
    KAGUYA_PP_INC(out,args.count)
    out.write('\n\n')
    KAGUYA_PP_DEC(out,args.count)
